package com.xbongbong.paas.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.xbongbong.paas.business.rule.BusinessRuleConditionHelp;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasStageEntity;
import com.xbongbong.paas.domain.entity.StageLogEntity;
import com.xbongbong.paas.domain.entity.StageProcessEntity;
import com.xbongbong.paas.domain.entity.StageWorkLogEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.StageTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.FilterConditionsPoJo;
import com.xbongbong.paas.help.FormDataHelp;
import com.xbongbong.paas.help.StageDetailHelp;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.StageProcessModel;
import com.xbongbong.paas.service.DetailStageService;
import com.xbongbong.paas.service.ProModelService;
import com.xbongbong.paas.service.stage.StageHandle;
import com.xbongbong.paas.service.stage.StageHandleFactory;
import com.xbongbong.paas.service.stage.StageJumpHandle;
import com.xbongbong.paas.service.stage.StageLogHandle;
import com.xbongbong.paas.service.stage.StageLogHandleFactory;
import com.xbongbong.paas.service.stage.jump.StageJumpFactory;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.parent.factory.StageExecuteFactory;
import com.xbongbong.parent.help.CommonPermissionHelp;
import com.xbongbong.parent.interfaces.StageExecuteHandle;
import com.xbongbong.pro.businessrule.pojo.BusinessRuleInfoPojo;
import com.xbongbong.pro.businesstage.pojo.dto.CommonJumpDTO;
import com.xbongbong.pro.businesstage.pojo.dto.StageDetailDTO;
import com.xbongbong.pro.businesstage.pojo.dto.StageExecutionEventGetDTO;
import com.xbongbong.pro.businesstage.pojo.dto.StageExecutionEventSaveDTO;
import com.xbongbong.pro.businesstage.pojo.dto.StageFinishWorkDTO;
import com.xbongbong.pro.businesstage.pojo.dto.StageGetDTO;
import com.xbongbong.pro.businesstage.pojo.dto.StageJumpDTO;
import com.xbongbong.pro.businesstage.pojo.dto.StageJumpValidateDTO;
import com.xbongbong.pro.businesstage.pojo.dto.StartJumpDTO;
import com.xbongbong.pro.businesstage.pojo.vo.CommonJumpVO;
import com.xbongbong.pro.businesstage.pojo.vo.StageDetailVO;
import com.xbongbong.pro.businesstage.pojo.vo.StageExecutionEventGetVO;
import com.xbongbong.pro.businesstage.pojo.vo.StageExecutionEventSaveVO;
import com.xbongbong.pro.businesstage.pojo.vo.StageFinishWorkVO;
import com.xbongbong.pro.businesstage.pojo.vo.StageGetVO;
import com.xbongbong.pro.businesstage.pojo.vo.StageJumpVO;
import com.xbongbong.pro.businesstage.pojo.vo.StartJumpVO;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.CustomerStageErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.UserTeamErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.dto.FormDataDetailDTO;
import com.xbongbong.pro.permission.pojo.dto.VerifyUpdatePermissionDTO;
import com.xbongbong.saas.domain.entity.SaleStageEntity;
import com.xbongbong.saas.domain.entity.StageWorkEntity;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.model.StageWorkModel;
import com.xbongbong.sys.help.PackageHelp;
import com.xbongbong.sys.help.ProPermissionHelp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author yingjianfeng
 * @Date: 2021/11/17 14:12
 * @Description: 详情页阶段相关
 */
@Service("detailStageService")
public class DetailStageServiceImpl implements DetailStageService {
    private static final Logger LOG = LoggerFactory.getLogger(DetailStageServiceImpl.class);
    @Resource
    private StageExecuteFactory stageExecuteFactory;
    @Resource
    private StageHandleFactory stageHandleFactory;
    @Resource
    private StageJumpFactory stageJumpFactory;
    @Resource
    private StageProcessModel stageProcessModel;
    @Resource
    private StageDetailHelp stageDetailHelp;
    @Resource
    private StageLogHandleFactory stageLogHandleFactory;
    @Resource
    private StageWorkModel stageWorkModel;
    @Resource
    private ProModelService proModelService;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private BusinessRuleConditionHelp businessRuleConditionHelp;
    @Resource
    private PackageHelp packageHelp;
    @Resource
    private FormDataHelp formDataHelp;
    @Resource
    private CommonPermissionHelp commonPermissionHelp;

    @Override
    public StageGetVO stageGet(StageGetDTO stageGetDTO) throws XbbException {
        Integer saasMark = stageGetDTO.getSaasMark();
        Integer businessType = stageGetDTO.getBusinessType();
        StageExecuteHandle stageExecute = stageExecuteFactory.getStageExecute(saasMark, businessType);
        return stageExecute.get(stageGetDTO);
    }


    @Override
    public StageDetailVO stageDetail(StageDetailDTO stagedetailDTO) throws XbbException {
        Integer saasMark = stagedetailDTO.getSaasMark();
        Integer businessType = stagedetailDTO.getBusinessType();
        StageExecuteHandle stageExecute = stageExecuteFactory.getStageExecute(saasMark, businessType);
        return stageExecute.detail(stagedetailDTO);
    }

    @Override
    public StageFinishWorkVO stageFinishWork(StageFinishWorkDTO stageFinishWorkDTO) throws XbbException {
        Integer saasMark = stageFinishWorkDTO.getSaasMark();
        Integer businessType = stageFinishWorkDTO.getBusinessType();
        StageExecuteHandle stageExecute = stageExecuteFactory.getStageExecute(saasMark, businessType);
        return stageExecute.finishWork(stageFinishWorkDTO);
    }

    @Override
    public StageExecutionEventSaveVO stageExecutionEventSave(StageExecutionEventSaveDTO stageExecutionEventSaveDTO) throws XbbException {
        Integer saasMark = stageExecutionEventSaveDTO.getSaasMark();
        Integer businessType = stageExecutionEventSaveDTO.getBusinessType();
        StageExecuteHandle stageExecute = stageExecuteFactory.getStageExecute(saasMark, businessType);
        return stageExecute.executionEventSave(stageExecutionEventSaveDTO);
    }

    @Override
    public StageExecutionEventGetVO stageExecutionEventGet(StageExecutionEventGetDTO stageExecutionEventGetDTO) throws XbbException {
        Integer saasMark = stageExecutionEventGetDTO.getSaasMark();
        Integer businessType = stageExecutionEventGetDTO.getBusinessType();
        StageExecuteHandle stageExecute = stageExecuteFactory.getStageExecute(saasMark, businessType);
        return stageExecute.executionEventGet(stageExecutionEventGetDTO);
    }

    @Override
    public StageJumpVO stageJump(StageJumpDTO stageJumpDTO) throws XbbException {
        StageJumpVO stageJumpVO = new StageJumpVO();
        String corpid = stageJumpDTO.getCorpid();
        Integer saasMark = stageJumpDTO.getSaasMark();
        Integer businessType = stageJumpDTO.getBusinessType();
        Long fromStageId = stageJumpDTO.getFromStageId();
        Long toStageId = stageJumpDTO.getToStageId();
        Long stageProcessId = stageJumpDTO.getStageProcessId();
        if (Objects.equals(fromStageId, toStageId)) {
            throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238004);
        }
        Integer toStageType = null;
        Integer fromStageType = null;
        PaasStageEntity toStageEntity = null;
        PaasStageEntity fromStageEntity = null;
        if (Objects.isNull(fromStageId)) {
            fromStageType = StageTypeEnum.START_STAGE.getType();
        } else {
            StageHandle stageHandle = stageHandleFactory.getStageHandle(saasMark, businessType);
            PaasStageEntity byKey = stageHandle.getByKey(fromStageId, corpid);
            if (Objects.nonNull(byKey)) {
                fromStageEntity = new SaleStageEntity();
                BeanUtils.copyProperties(byKey, fromStageEntity);
                fromStageType = fromStageEntity.getType();
            }
        }
        if (Objects.isNull(toStageId)) {
            toStageType = StageTypeEnum.START_STAGE.getType();
        } else {
            StageHandle stageHandle = stageHandleFactory.getStageHandle(saasMark, businessType);
            PaasStageEntity byKey = stageHandle.getByKey(toStageId, corpid);
            if (Objects.nonNull(byKey)) {
                toStageEntity = new SaleStageEntity();
                BeanUtils.copyProperties(byKey, toStageEntity);
                toStageType = toStageEntity.getType();
            }
        }
        StageJumpValidateDTO stageJumpValidateDTO = new StageJumpValidateDTO();
        BeanUtils.copyProperties(stageJumpDTO, stageJumpValidateDTO);
        stageJumpValidateDTO.setFromStageEntity(fromStageEntity);
        stageJumpValidateDTO.setToStageEntity(toStageEntity);
        stageJumpValidateDTO.setToStageType(toStageType);
        stageJumpValidateDTO.setFromStageType(fromStageType);
        StageProcessEntity stageProcessEntity = stageProcessModel.getByKey(stageProcessId, corpid);
        stageJumpValidateDTO.setStageProcessEntity(stageProcessEntity);
        StageExecuteHandle stageExecute = stageExecuteFactory.getStageExecute(saasMark, businessType);
        // 跳转校验 不同阶段类型的校验
        validate(stageJumpValidateDTO);
        // 跳转校验 不同业务类型的校验
        stageExecute.validate(stageJumpValidateDTO);
        // 开始跳转
        StartJumpDTO startJumpDTO = new StartJumpDTO();
        BeanUtils.copyProperties(stageJumpValidateDTO, startJumpDTO);
        StartJumpVO startJumpVO = stageExecute.startJump(startJumpDTO);
        BeanUtils.copyProperties(startJumpVO, stageJumpVO);
        return stageJumpVO;
    }


    @Override
    public CommonJumpVO commonJump(CommonJumpDTO commonJumpDTO) throws XbbException {
        StageExecuteHandle stageExecute = stageExecuteFactory.getStageExecute(commonJumpDTO.getSaasMark(), commonJumpDTO.getBusinessType());
        return stageExecute.stageCommonJump(commonJumpDTO);
    }

    /**
     * description:  这里写通用的校验，即所有阶段都会有的校验。每个阶段的特殊校验写在stageJump.validate(stageJumpValidateDTO);中
     * date: 2021/12/14 9:45 上午
     *
     * @Author yingjf
     */
    public void validate(StageJumpValidateDTO stageJumpValidateDTO) throws XbbException {
        Integer toStageType = stageJumpValidateDTO.getToStageType();
        Integer fromStageType = stageJumpValidateDTO.getFromStageType();
        Integer saasMark = stageJumpValidateDTO.getSaasMark();
        Integer businessType = stageJumpValidateDTO.getBusinessType();
        String corpid = stageJumpValidateDTO.getCorpid();
        Long formId = stageJumpValidateDTO.getFormId();
        Long dataId = stageJumpValidateDTO.getDataId();
        String userId = stageJumpValidateDTO.getUserId();
        Long menuId = stageJumpValidateDTO.getMenuId();
        UserVO loginUser = stageJumpValidateDTO.getLoginUser();
        PaasStageEntity toStageEntity = stageJumpValidateDTO.getToStageEntity();
        PaasStageEntity fromStageEntity = stageJumpValidateDTO.getFromStageEntity();
        StageProcessEntity stageProcessEntity = stageJumpValidateDTO.getStageProcessEntity();
        Long stageProcessId = stageProcessEntity.getId();
        StageExecuteHandle stageExecute = stageExecuteFactory.getStageExecute(saasMark, businessType);
        PaasFormDataEntityExt paasFormDataEntityExt = formDataHelp.getFormDataWithTeam(corpid, saasMark, businessType, dataId);
        //套餐版本校验
        Integer feeType = packageHelp.getFeeType(stageJumpValidateDTO.getCorpid());
        boolean packageSatisfy = Objects.equals(feeType, PackageTypeEnum.ULTIMATE.getType());
        if (paasFormDataEntityExt == null || 1 == paasFormDataEntityExt.getDel()) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100404);
        }
        // 成功和失败阶段不能互跳
        if (fromStageType > 0 && toStageType > 0) {
            //结束阶段不可相互跳转
            throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238039);
        }
        // 不能跳入未启用阶段
        if (Objects.nonNull(toStageEntity) && Objects.equals(toStageEntity.getEnable(), 0)) {
            throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238066);
        }
        Integer isStageView = stageJumpValidateDTO.getIsStageView();
        // 泳道视图的特殊校验
        if (Objects.nonNull(isStageView) && Objects.equals(isStageView, 1)) {
            //校验套餐类型
            if (packageSatisfy) {
                // 泳道图从其它阶段跳出  需校验触发事件
                JSONArray triggerCondition = stageProcessEntity.getTriggerCondition();
                if (Objects.isNull(fromStageEntity)) {
                    Integer enable = stageProcessEntity.getEnable();
                    if (Objects.equals(enable, 0)) {
                        //此阶段流程未启用!
                        throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238054);
                    }
                    if (CollectionsUtil.isNotEmpty(triggerCondition)) {
                        List<FilterConditionsPoJo> triggerConditionPojos = triggerCondition.toJavaList(FilterConditionsPoJo.class);
                        // fix 判断触发条件
                        PaasFormExplainEntity explain = paasFormExplainModel.getByFormId(formId, corpid);
                        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(explain.getExplains(), null);
                        BusinessRuleInfoPojo businessRuleInfoPojo = new BusinessRuleInfoPojo(corpid, formId, businessType, saasMark, explainMap);
                        boolean validateRes = businessRuleConditionHelp.validatePreCondition(triggerConditionPojos, paasFormDataEntityExt, businessRuleInfoPojo);
                        if (!validateRes) {
                            // 不满足触发条件
                            throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238051);
                        }
                    }
                }
            }
            // 校验跳转
            //● 客户、线索、机会不支持在列表页将阶段拖动到结束阶段，因为有些特殊逻辑需要处理，比如填写输单原因。合同阶段用的是Paas字段，没有特殊逻辑，所以可以操作
            //● “未分组阶段”移动至“普通阶段、结束阶段”时，会进行“目标阶段是否是启用中的版本”、“触发条件”的判断
            if (Objects.equals(saasMark, SaasMarkEnum.SAAS.getCode()) && !Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode())) {
                if (toStageType > 0) {
                    throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238063);
                }
            }
        }
        //校验任务执行人  当不填写时，任何有此字段编辑权限的用户都可以推进到此阶段，当选择时，仅选择的用户支持推进到此阶段
        if (toStageEntity == null) {
            // 跳到开始阶段
            if (!stageExecute.checkFieldEditable(stageJumpValidateDTO)) {
                throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238030);
            }
        } else {
            JSONArray executor = toStageEntity.getExecutor();
            //校验套餐类型
            if (packageSatisfy && CollectionsUtil.isNotEmpty(executor)) {
                // fix 校验阶段推进人
                boolean checkUser = stageDetailHelp.checkUser(corpid, saasMark, businessType, dataId, executor, userId);
                if (!checkUser) {
                    //您不是阶段推进人
                    throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238050);
                }
            } else {
                // 校验表单编辑权限
                VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO();
                BeanUtil.copyProperties(stageJumpValidateDTO, verifyUpdatePermissionDTO);
                ProPermissionHelp.verifyEditPermission(verifyUpdatePermissionDTO);
                //您没有阶段字段编辑权限
                if (!stageExecute.checkFieldEditable(stageJumpValidateDTO)) {
                    throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238030);
                }
                verifyUpdatePermissionDTO.setPaasFormDataEntityExt(paasFormDataEntityExt);
                boolean dataEditPermission = commonPermissionHelp.checkEditPermissionWithoutTeamEdit(verifyUpdatePermissionDTO);
                if (!dataEditPermission) {
                    throw new XbbException(UserTeamErrorCodeEnum.API_ERROR_271042);
                }
            }
        }
        StageJumpHandle stageJump = stageJumpFactory.getStageJump(toStageType);
        StageLogHandle stageLogHandle = stageLogHandleFactory.getStageLogHandle(saasMark, businessType);
        Long stageLogId = null;

        // 校验当前阶段是否是isnow阶段 开始阶段除外
        stageLogId = validateFromStageIsNow(stageLogHandle, fromStageEntity, dataId);
        // 校验
        stageJump.validate(stageJumpValidateDTO);
        // 校验当前阶段是否完成必填任务
        validateRequiredWork(stageJumpValidateDTO, stageExecute, stageLogId);

        // 从开始阶段调过来那就代表没有isnow=1的log记录 需要处理下
        if (Objects.isNull(fromStageEntity) || Objects.equals(fromStageType, StageTypeEnum.START_STAGE.getType())) {
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put("corpid", corpid);
            params.put("formId", formId);
            params.put("dataId", dataId);
            List<StageLogEntity> stageLogEntities = stageLogHandle.findEntitys(params);
            List<StageLogEntity> needResetIsNowStageLogList = new ArrayList<>();
            for (StageLogEntity temp : stageLogEntities) {
                Integer isNow = temp.getIsNow();
                if (Objects.equals(isNow, 1)) {
                    temp.setIsNow(0);
                    needResetIsNowStageLogList.add(temp);
                }
            }
            if (CollectionsUtil.isNotEmpty(needResetIsNowStageLogList)) {
                stageLogHandle.save(needResetIsNowStageLogList.get(0));
            }
        }


    }

    /**
     * 校验当前阶段是否是 isnow 阶段 开始阶段除外
     *
     * @param stageLogHandle
     * @param fromStageEntity
     * @param dataId
     * @return
     * @throws XbbException
     */
    private Long validateFromStageIsNow(StageLogHandle stageLogHandle, PaasStageEntity fromStageEntity, Long dataId) throws XbbException {
        //开始阶段并发不会出现问题,因为此方法后有代码重置了isNow,关键词可搜：needResetIsNowStageLogList
        if (Objects.isNull(fromStageEntity)
                || Objects.equals(fromStageEntity.getType(), StageTypeEnum.START_STAGE.getType())) {
            return null;
        }

        Long stageId = fromStageEntity.getId();
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("corpid", fromStageEntity.getCorpid());
        params.put("formId", fromStageEntity.getFormId());
        params.put("dataId", dataId);
        params.put("stageId", stageId);
        params.put("del", 0);
        List<StageLogEntity> stageLogEntityList = stageLogHandle.findEntitys(params);
        StageLogEntity stageLogEntity = null;
        if (CollectionsUtil.isNotEmpty(stageLogEntityList)) {
            stageLogEntity = stageLogEntityList.get(0); // ArrayIndexOutOfBoundsException
        }
        if (Objects.isNull(stageLogEntity) || !Objects.equals(stageLogEntity.getIsNow(), 1)) {
            throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238048);
        }
        return stageLogEntity.getId();
    }

    /**
     * 校验必填任务
     *
     * @param stageJumpValidateDTO
     * @param stageExecute
     * @param stageLogId
     * @throws XbbException
     */
    private void validateRequiredWork(StageJumpValidateDTO stageJumpValidateDTO, StageExecuteHandle stageExecute, Long stageLogId) throws XbbException {
        PaasStageEntity fromStageEntity = stageJumpValidateDTO.getFromStageEntity();
        PaasStageEntity toStageEntity = stageJumpValidateDTO.getToStageEntity();

        //开始阶段无需校验必填任务,且正好与validateFromStageIsNow 对应，stageLogId不会为 null
        if (Objects.isNull(fromStageEntity)
                || Objects.equals(fromStageEntity.getType(), StageTypeEnum.START_STAGE.getType())) {
            return;
        }

        // 结束阶段开启 enableJumpEnd按钮时,不校验必填
        if (Objects.nonNull(toStageEntity) && StageTypeEnum.getEndType().contains(toStageEntity.getType())
                && Objects.equals(toStageEntity.getEnableJumpEnd(), 1)) {
            return;
        }

        // fix: 2021/12/8 必填任务校验  只校验当前阶段的必填情况   回退不校验必填任务
        if (toStageEntity.getSort() < fromStageEntity.getSort()) {

            Long stageId = fromStageEntity.getId();
            String stageName = fromStageEntity.getName();
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put("corpid", stageJumpValidateDTO.getCorpid());
            params.put("formId", stageJumpValidateDTO.getFormId());
            params.put("stageId", stageId);
            params.put("stageProcessId", stageJumpValidateDTO.getStageProcessEntity().getId());
            params.put("del", 0);
            List<StageWorkEntity> workEntityList = stageWorkModel.findEntitys(params);
            params.clear();
            params.put("corpid", stageJumpValidateDTO.getCorpid());
            params.put("stageId", stageId);
            params.put("stageLogId", stageLogId);
            params.put("del", 0);
            List<StageWorkLogEntity> stageWorkLogEntityList = stageExecute.stageWorkLogFindEntitys(params);
            Map<Long, StageWorkLogEntity> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (StageWorkLogEntity temp : stageWorkLogEntityList) {
                map.put(temp.getStageWorkId(), temp);
            }
            for (StageWorkEntity temp : workEntityList) {
                Long id = temp.getId();
                Integer required = temp.getRequired();
                if (Objects.equals(required, 1)) {
                    StageWorkLogEntity stageWorkLogEntity = map.get(id);
                    // 没做过
                    if (Objects.isNull(stageWorkLogEntity)) {
                        throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238032, String.format(CustomerStageErrorCodeEnum.API_ERROR_238032.getMsg(), stageName));
                    }
                    // 没完成
                    Integer isFinished = stageWorkLogEntity.getIsFinished();
                    if (Objects.equals(isFinished, 0)) {
                        throw new XbbException(CustomerStageErrorCodeEnum.API_ERROR_238032, String.format(CustomerStageErrorCodeEnum.API_ERROR_238032.getMsg(), stageName));
                    }
                }
            }
        }
    }

}
